home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
avril20
/
drvcyman.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-21
|
5KB
|
152 lines
/* Logitech Cyberman support for AVRIL */
/* Written by Bernie Roehl, July 1994 */
/* Copyright 1994 by Bernie Roehl */
/* You may use this code for your own non-commercial projects without
paying any fees or royalties. "Non-commercial", in this context,
means that the software you write is given away for free to anyone
who wants it.
Commercial use, including shareware, requires a licensing
fee and a specific written agreement with the author.
All programs created using this software (both commercial and
non-commercial) must acknowledge the use of the AVRIL library,
both in the documentation and in a banner screen at the start or
end of the program.
For more information, contact Bernie Roehl (broehl@uwaterloo.ca).
*/
#include "avril.h"
static vrl_DeviceChannel cybchannel_defaults[] =
{
/* center, deadzone, range, scale, accum */
{ 0, 5, 128, float2scalar(1000), 1 }, /* trans X */
{ 0, 0, 1, float2scalar(1000), 1 }, /* trans Y */
{ 0, 5, -128, float2scalar(1000), 1 }, /* trans Z */
{ 0, 0, -1, float2angle(20), 1 }, /* rot X */
{ 0, 0, -1, float2angle(20), 1 }, /* rot Y */
{ 0, 0, 1, float2angle(20), 1 } /* rot Z */
};
static void reset_cyberman(vrl_SerialPort *port)
{
vrl_SerialSetDTR(port, 1); /* DTR high */
vrl_SerialSetRTS(port, 0); /* RTS low */
vrl_TimerDelay(200); /* spec says 100, but let's be generous */
vrl_SerialSetRTS(port, 1); /* RTS high */
vrl_TimerDelay(400); /* 110 for first char, 100 for second */
}
static int values[] = { 0, 1, -1, 0 };
int vrl_CybermanOutput(vrl_Device *dev, int parm1, vrl_Scalar parm2)
{
unsigned char val = ((vrl_32bit) scalar2float(parm2)) & 0xFF;
if (parm1) return -1;
vrl_SerialPutc('!', dev->port);
vrl_SerialPutc('T', dev->port);
vrl_SerialPutc(val, dev->port);
vrl_SerialPutc(255 - val, dev->port);
vrl_SerialPutc((val == 0) ? 0 : 7, dev->port); /* 280 ms */
return 0;
}
int vrl_CybermanDevice(vrl_DeviceCommand cmd, vrl_Device *device)
{
switch (cmd)
{
case VRL_DEVICE_INIT:
if (device->port == NULL) return -4;
device->nchannels = 6;
device->channels = vrl_calloc(device->nchannels, sizeof(vrl_DeviceChannel));
if (device->channels == NULL) return -1;
device->localdata = vrl_DeviceCreatePacketBuffer(5);
if (device->localdata == NULL)
{
vrl_free(device->channels);
device->channels = NULL;
return -1;
}
device->nbuttons = 3;
device->noutput_channels = 1;
device->outfunc = vrl_CybermanOutput;
device->desc = "Logitech Cyberman, direct serial";
device->version = 1;
case VRL_DEVICE_RESET:
vrl_SerialSetParameters(device->port, 1200, VRL_PARITY_NONE, 7, 1);
reset_cyberman(device->port);
/* look for the 'M3' identification sequence */
if (!vrl_SerialCheck(device->port)) return -2;
if (vrl_SerialGetc(device->port) != 'M') return -3;
if (!vrl_SerialCheck(device->port)) return -2;
if (vrl_SerialGetc(device->port) != '3') return -3;
/* enter Swift mode */
vrl_SerialPutc('*', device->port); vrl_SerialPutc('S', device->port);
vrl_TimerDelay(500);
vrl_SerialSetParameters(device->port, 4800, VRL_PARITY_NONE, 8, 1);
vrl_TimerDelay(200);
vrl_SerialFlush(device->port);
/* request a Static Device Status report */
vrl_SerialPutc('!', device->port); vrl_SerialPutc('S', device->port);
vrl_TimerDelay(500); /* wait for the report to come in */
while (vrl_SerialCheck(device->port))
if ((vrl_SerialGetc(device->port) & 0xE0) == 0xA0)
break;
if (!vrl_SerialCheck(device->port))
{
reset_cyberman(device->port);
return -2; /* no report */
}
vrl_SerialFlush(device->port);
memcpy(device->channels, cybchannel_defaults, sizeof(cybchannel_defaults));
return 0;
case VRL_DEVICE_POLL:
while (vrl_DeviceGetPacket(device->port, device->localdata))
{
unsigned char *p = vrl_DevicePacketGetBuffer(device->localdata);
int x, y, i;
unsigned int b;
if ((p[0] & 0xE0) != 0x80) continue; /* ignore non-data packets */
b = p[0] & 0x1F;
device->bchanged = b ^ device->buttons;
device->buttons = b;
x = (p[1] << 1) | ((p[2] >> 6) & 0x01);
y = (p[2] << 2) | ((p[3] >> 5) & 0x03);
if (x & 0x80) x |= 0xFF00; /* sign extend */
else x &= 0xFF;
if (y & 0x80) y |= 0xFF00; /* sign extend */
else y &= 0xFF;
device->channels[X].rawvalue = x;
device->channels[Y].rawvalue = values[(p[3] >> 3) & 0x03];
device->channels[Z].rawvalue = y;
device->channels[XROT].rawvalue = values[(p[3] >> 1) & 0x03];
device->channels[YROT].rawvalue = values[(p[4] >> 4) & 0x03];
device->channels[ZROT].rawvalue = values[((p[3] << 1) | ((p[4] >> 6) & 0x01)) & 0x03];
for (i = 0; i < 6; ++i)
device->channels[i].changed = 1;
}
return 0;
case VRL_DEVICE_QUIT:
reset_cyberman(device->port);
if (device->localdata)
{
vrl_DeviceDestroyPacketBuffer(device->localdata);
device->localdata = NULL;
}
if (device->channels)
{
vrl_free(device->channels);
device->channels = NULL;
}
return 0;
default: break;
}
return 1; /* function not implemented */
}